package agent

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"regexp"
	"strings"
	"time"
)

// Planner 计划器
type Planner struct {
	llm     LLMInterface
	tools   *ToolManager
	timeout time.Duration
}

// NewPlanner 创建新的计划器
func NewPlanner(llm LLMInterface, tools *ToolManager, timeout time.Duration) *Planner {
	return &Planner{
		llm:     llm,
		tools:   tools,
		timeout: timeout,
	}
}

// CreatePlan 创建执行计划
func (p *Planner) CreatePlan(ctx context.Context, userMessage string, recentMessages []Message) (*Plan, error) {
	log.Printf("[PLANNER] 📋 开始制定计划，用户消息: %s", userMessage)

	// 1. 分析用户意图
	intent, err := p.analyzeIntent(ctx, userMessage, recentMessages)
	if err != nil {
		log.Printf("[PLANNER] ❌ 意图分析失败: %v", err)
		return nil, err
	}

	log.Printf("[PLANNER] 🎯 意图分析结果: %s (置信度: %.2f)", intent.Type, intent.Confidence)

	// 2. 根据意图创建计划
	plan, err := p.createPlanForIntent(intent, userMessage)
	if err != nil {
		log.Printf("[PLANNER] ❌ 创建计划失败: %v", err)
		return nil, err
	}

	log.Printf("[PLANNER] ✅ 计划创建成功，步骤数: %d", len(plan.Steps))
	return plan, nil
}

// analyzeIntent 分析用户意图
func (p *Planner) analyzeIntent(ctx context.Context, userMessage string, recentMessages []Message) (*Intent, error) {
	// 首先使用规则基础的快速分析
	if intent := p.quickIntentAnalysis(userMessage); intent != nil {
		return intent, nil
	}

	// 如果快速分析无法确定，使用LLM进行深度分析
	return p.llmIntentAnalysis(ctx, userMessage, recentMessages)
}

// quickIntentAnalysis 快速意图分析（基于规则）
func (p *Planner) quickIntentAnalysis(message string) *Intent {
	message = strings.ToLower(message)

	// 时间查询模式
	timePatterns := []string{
		`(现在|当前|几点|时间).*?(北京|上海|东京|纽约|伦敦|巴黎|洛杉矶|悉尼|新加坡|香港|台北|首尔|莫斯科|迪拜|孟买|曼谷|雅加达|马尼拉|吉隆坡|河内)`,
		`(北京|上海|东京|纽约|伦敦|巴黎|洛杉矶|悉尼|新加坡|香港|台北|首尔|莫斯科|迪拜|孟买|曼谷|雅加达|马尼拉|吉隆坡|河内).*?(现在|当前|几点|时间)`,
		`查询.*?(时间|几点)`,
	}

	for _, pattern := range timePatterns {
		if matched, _ := regexp.MatchString(pattern, message); matched {
			location := p.extractLocation(message)
			if location == "" {
				location = "北京" // 默认地点
			}
			return &Intent{
				Type:       "time_query",
				Confidence: 0.9,
				Parameters: map[string]interface{}{
					"location": location,
				},
				Entities: []Entity{
					{Type: "location", Value: location},
				},
			}
		}
	}

	// 计算模式
	calcPatterns := []string{
		`(计算|算|等于).*?[\d+\-*/()sqrt pow]`,
		`[\d+\-*/()]+.*?(等于|是多少|结果)`,
		`\d+\s*[+\-*/]\s*\d+`,
		`sqrt\s*\(\s*\d+\s*\)`,
		`pow\s*\(\s*\d+\s*,\s*\d+\s*\)`,
	}

	for _, pattern := range calcPatterns {
		if matched, _ := regexp.MatchString(pattern, message); matched {
			expression := p.extractExpression(message)
			return &Intent{
				Type:       "calculation",
				Confidence: 0.85,
				Parameters: map[string]interface{}{
					"expression": expression,
				},
				Entities: []Entity{
					{Type: "expression", Value: expression},
				},
			}
		}
	}

	// 记忆搜索模式
	memoryPatterns := []string{
		`(记得|还记得|之前|以前|刚才).*?(说|提到|聊)`,
		`(查找|搜索|找找).*?(历史|记录|之前)`,
		`我们.*?(聊过|说过|讨论过)`,
	}

	for _, pattern := range memoryPatterns {
		if matched, _ := regexp.MatchString(pattern, message); matched {
			query := p.extractSearchQuery(message)
			return &Intent{
				Type:       "memory_search",
				Confidence: 0.8,
				Parameters: map[string]interface{}{
					"query": query,
				},
				Entities: []Entity{
					{Type: "keyword", Value: query},
				},
			}
		}
	}

	return nil // 无法快速确定意图
}

// llmIntentAnalysis 使用LLM进行意图分析
func (p *Planner) llmIntentAnalysis(ctx context.Context, userMessage string, recentMessages []Message) (*Intent, error) {
	// 构建上下文
	contextStr := ""
	for _, msg := range recentMessages {
		contextStr += fmt.Sprintf("%s: %s\n", msg.Role, msg.Content)
	}

	prompt := fmt.Sprintf(`请分析以下用户消息的意图，并返回JSON格式的结果。

可能的意图类型：
1. time_query - 时间查询（查询某地当前时间）
2. calculation - 数学计算（进行数学运算）
3. memory_search - 记忆搜索（搜索历史对话）
4. chat - 普通聊天（一般对话）

对话历史：
%s

用户消息：%s

请返回JSON格式：
{
  "type": "意图类型",
  "confidence": 置信度(0-1),
  "parameters": {
    "location": "地点名称（仅时间查询）",
    "expression": "数学表达式（仅计算）",
    "query": "搜索关键词（仅记忆搜索）"
  },
  "entities": [
    {"type": "实体类型", "value": "实体值"}
  ]
}`, contextStr, userMessage)

	messages := []LLMMessage{
		{Role: "system", Content: "你是一个意图分析专家，请准确分析用户意图并返回JSON格式结果。"},
		{Role: "user", Content: prompt},
	}

	response, err := p.llm.GenerateResponse(ctx, messages)
	if err != nil {
		return nil, err
	}

	// 解析JSON响应
	var intent Intent
	if err := json.Unmarshal([]byte(response), &intent); err != nil {
		// 如果JSON解析失败，回退到默认聊天意图
		log.Printf("[PLANNER] ⚠️ LLM意图分析JSON解析失败，回退到聊天意图: %v", err)
		return &Intent{
			Type:       "chat",
			Confidence: 0.5,
			Parameters: map[string]interface{}{},
			Entities:   []Entity{},
		}, nil
	}

	return &intent, nil
}

// createPlanForIntent 根据意图创建计划
func (p *Planner) createPlanForIntent(intent *Intent, userMessage string) (*Plan, error) {
	plan := &Plan{
		ID:          generateID(),
		Description: fmt.Sprintf("处理%s类型的请求", intent.Type),
		Steps:       []PlanStep{},
		CreatedAt:   time.Now(),
	}

	switch intent.Type {
	case "time_query":
		return p.createTimeQueryPlan(plan, intent)
	case "calculation":
		return p.createCalculationPlan(plan, intent)
	case "memory_search":
		return p.createMemorySearchPlan(plan, intent)
	case "chat":
		return p.createChatPlan(plan, intent, userMessage)
	default:
		return p.createChatPlan(plan, intent, userMessage)
	}
}

// createTimeQueryPlan 创建时间查询计划
func (p *Planner) createTimeQueryPlan(plan *Plan, intent *Intent) (*Plan, error) {
	location, ok := intent.Parameters["location"].(string)
	if !ok {
		location = "北京"
	}

	step := PlanStep{
		ID:          generateID(),
		Type:        "tool_call",
		Description: fmt.Sprintf("查询%s的当前时间", location),
		ToolName:    "get_time",
		Parameters: map[string]interface{}{
			"location": location,
		},
		Order: 1,
	}

	plan.Steps = append(plan.Steps, step)
	plan.Description = fmt.Sprintf("查询%s的当前时间", location)
	return plan, nil
}

// createCalculationPlan 创建计算计划
func (p *Planner) createCalculationPlan(plan *Plan, intent *Intent) (*Plan, error) {
	expression, ok := intent.Parameters["expression"].(string)
	if !ok {
		return nil, fmt.Errorf("缺少计算表达式")
	}

	step := PlanStep{
		ID:          generateID(),
		Type:        "tool_call",
		Description: fmt.Sprintf("计算表达式: %s", expression),
		ToolName:    "calculate",
		Parameters: map[string]interface{}{
			"expression": expression,
		},
		Order: 1,
	}

	plan.Steps = append(plan.Steps, step)
	plan.Description = fmt.Sprintf("计算: %s", expression)
	return plan, nil
}

// createMemorySearchPlan 创建记忆搜索计划
func (p *Planner) createMemorySearchPlan(plan *Plan, intent *Intent) (*Plan, error) {
	query, ok := intent.Parameters["query"].(string)
	if !ok {
		return nil, fmt.Errorf("缺少搜索关键词")
	}

	step := PlanStep{
		ID:          generateID(),
		Type:        "tool_call",
		Description: fmt.Sprintf("搜索记忆: %s", query),
		ToolName:    "search_memory",
		Parameters: map[string]interface{}{
			"query": query,
		},
		Order: 1,
	}

	plan.Steps = append(plan.Steps, step)
	plan.Description = fmt.Sprintf("搜索记忆: %s", query)
	return plan, nil
}

// createChatPlan 创建聊天计划
func (p *Planner) createChatPlan(plan *Plan, intent *Intent, userMessage string) (*Plan, error) {
	step := PlanStep{
		ID:          generateID(),
		Type:        "llm_query",
		Description: "生成聊天回复",
		Parameters: map[string]interface{}{
			"message": userMessage,
		},
		Order: 1,
	}

	plan.Steps = append(plan.Steps, step)
	plan.Description = "普通聊天对话"
	return plan, nil
}

// 辅助函数

// extractLocation 提取地点信息
func (p *Planner) extractLocation(message string) string {
	locations := []string{
		"北京", "上海", "东京", "纽约", "伦敦", "巴黎", "洛杉矶", "悉尼",
		"新加坡", "香港", "台北", "首尔", "莫斯科", "迪拜", "孟买", "曼谷",
		"雅加达", "马尼拉", "吉隆坡", "河内",
	}

	message = strings.ToLower(message)
	for _, location := range locations {
		if strings.Contains(message, strings.ToLower(location)) {
			return location
		}
	}

	return ""
}

// extractExpression 提取数学表达式
func (p *Planner) extractExpression(message string) string {
	// 移除常见的中文描述词
	message = strings.ReplaceAll(message, "计算", "")
	message = strings.ReplaceAll(message, "等于多少", "")
	message = strings.ReplaceAll(message, "是多少", "")
	message = strings.ReplaceAll(message, "？", "")
	message = strings.ReplaceAll(message, "?", "")
	message = strings.ReplaceAll(message, " ", "")

	// 替换中文运算符
	message = strings.ReplaceAll(message, "加", "+")
	message = strings.ReplaceAll(message, "减", "-")
	message = strings.ReplaceAll(message, "乘以", "*")
	message = strings.ReplaceAll(message, "乘", "*")
	message = strings.ReplaceAll(message, "除以", "/")
	message = strings.ReplaceAll(message, "除", "/")
	message = strings.ReplaceAll(message, "的平方根", "")
	message = strings.ReplaceAll(message, "平方根", "sqrt")
	message = strings.ReplaceAll(message, "的", "")
	message = strings.ReplaceAll(message, "次方", "")

	// 处理平方根
	if strings.Contains(message, "sqrt") && !strings.Contains(message, "(") {
		re := regexp.MustCompile(`sqrt(\d+)`)
		message = re.ReplaceAllString(message, "sqrt($1)")
	}

	// 处理幂运算
	if strings.Contains(message, "pow") || (strings.Contains(message, "的") && strings.Contains(message, "次方")) {
		parts := strings.Split(message, "的")
		if len(parts) == 2 {
			base := strings.TrimSpace(parts[0])
			exp := strings.TrimSpace(strings.ReplaceAll(parts[1], "次方", ""))
			return fmt.Sprintf("pow(%s,%s)", base, exp)
		}
	}

	return strings.TrimSpace(message)
}

// extractSearchQuery 提取搜索关键词
func (p *Planner) extractSearchQuery(message string) string {
	// 移除常见的搜索提示词
	stopWords := []string{
		"记得", "还记得", "之前", "以前", "刚才", "查找", "搜索", "找找",
		"历史", "记录", "我们", "聊过", "说过", "讨论过", "提到", "聊", "说",
	}

	words := strings.Fields(message)
	var filteredWords []string

	for _, word := range words {
		isStopWord := false
		for _, stopWord := range stopWords {
			if strings.Contains(word, stopWord) {
				isStopWord = true
				break
			}
		}
		if !isStopWord && len(word) > 1 {
			filteredWords = append(filteredWords, word)
		}
	}

	if len(filteredWords) > 0 {
		return strings.Join(filteredWords, " ")
	}

	return message // 如果无法提取，返回原消息
}
